# Copyright (C) Maciej Suminski <orson@orson.net.pl>
# Copyright (C) 2020 Seth Hillbrand <seth@kipro-pcb.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may find one here:
# https://www.gnu.org/licenses/gpl-3.0.html
# or you may search the http://www.gnu.org website for the version 3 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

import logging
import sentry_sdk
from gitlab import Gitlab
from fastapi import (
    FastAPI, Request, Response, status, BackgroundTasks,
    HTTPException, Header, Depends
)
from .config import (
    GITLAB_URL,
    GITLAB_TOKEN,
    GITLAB_SECRET,
    KICAD_CODE_PROJECT_PATH,
    SENTRY_DSN
)
from .handlers import BannedUsersHandler, CodeIssueHandler

logger = logging.getLogger(__name__)


async def verify_token(x_gitlab_token: str = Header(default='')):
    if x_gitlab_token != GITLAB_SECRET:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)


def handler_task(event: str, payload: dict):
    gitlab = Gitlab(GITLAB_URL, private_token=GITLAB_TOKEN,
                    retry_transient_errors=True)

    handler = BannedUsersHandler(gitlab)

    if handler.handle(event, payload):
        return

    if event != 'Issue Hook':
        logger.debug('Gitlab event not an issue: ' + event)
        return

    # Process Code issue template requirements
    if payload['project']['path_with_namespace'] == KICAD_CODE_PROJECT_PATH:
        handler = CodeIssueHandler(gitlab)
        handler.handle(event, payload)
    else:
        logger.debug('Skipping event for ' +
                     payload['project']['path_with_namespace'])


if SENTRY_DSN:
    sentry_sdk.init(
        dsn=SENTRY_DSN,

        # Set traces_sample_rate to 1.0 to capture 100%
        # of transactions for performance monitoring.
        # We recommend adjusting this value in production,
        traces_sample_rate=1.0,
    )

app = FastAPI(dependencies=[Depends(verify_token)])


@app.post('/issue')
async def issue(
        request: Request,
        bg_tasks: BackgroundTasks,
        x_gitlab_event: str = Header(default='')) -> Response:
    try:
        payload = await request.json()
    except BaseException as e:
        logger.error('Can not parse payload json', exc_info=e)
        return Response(status_code=status.HTTP_400_BAD_REQUEST)

    bg_tasks.add_task(handler_task, x_gitlab_event, payload)

    return Response(content='OK', status_code=status.HTTP_202_ACCEPTED, background=bg_tasks)
